<?php

namespace app\command;

use app\admin\model\Config;
use app\model\AdminAgent;
use app\model\AgentDistribution;
use app\model\AgentShop;
use app\model\DistributionSetting;
use app\model\Goods;
use app\model\GoodsFree;
use app\model\Order;
use app\model\OrderInfo;
use app\model\OrderTeamCommissionLogModel;
use app\model\User;
use app\model\UserBalanceLog;
use app\service\OrderService;
use Exception;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\Output;
use think\Db;
use think\facade\Log;
use Wechat\CommerceApp;

class OrderCommand extends Command
{
	protected function configure()
	{
		$startTime = date('Y-m-d 00:00:00', strtotime('-1 day'));
		$endTime   = date('Y-m-d 23:59:59', strtotime('-1 day'));

		$this->setName('order')
			->addArgument('startTime', Argument::OPTIONAL, '开始时间', $startTime)
			->addArgument('endTime', Argument::OPTIONAL, '结束时间', $endTime)
			->setDescription('获取佣金单列表');
	}

	/**
	 * @throws Exception
	 * 每日凌晨1点执行，处理上一天的订单
	 */
	protected function execute(Input $input, Output $output)
	{
		$startTime = $input->getArgument('startTime');
		$endTime   = $input->getArgument('endTime');

		Log::init([
			'type'        => 'file',
			'apart_level' => ['error'],
			'level'       => ['error'],
			'path'        => app()->getRootPath() . "runtime/log/order/",
			'max_files'   => 15,
		]);

		$this->handleData($startTime, $endTime);
	}


	/**
	 * @throws Exception
	 */
	private function handleData($startTime, $endTime)
	{
		$nextKey = '';
		do {
			[$orders, $nextKey] = CommerceApp::getInstance()->getOrderList($nextKey, '', strtotime($startTime), strtotime($endTime));
			if (empty($orders)) {
				echo "日期：{$startTime}--{$endTime}\n";
				echo "无数据跳过\n";
				exit;
			}

			$orderIds = [];
			foreach ($orders as $item) {
				$orderIds[] = $item['order_id'];
			}

			$orderListMap = Order::where('order_id', 'in', $orderIds)->column('order_id, id');

			foreach ($orders as $item) {
				$orderId = $item['order_id'];
				$skuId   = $item['sku_id'];

				if (empty($orderListMap[$orderId])) {
					$this->createOrderHandle($orderId, $skuId, $item, $nextKey, $startTime);
				} else {
					$this->updateOrderHandle($orderId, $skuId, $item, $nextKey, $startTime);
				}
			}
		} while (!empty($nextKey));

	}


	private function createOrderHandle($orderId, $skuId, $item, $nextKey, $startTime): void
	{
		// 如果不存在，任何状态都需要拉过来
		try {
			$orderRes = CommerceApp::getInstance()->getOrderInfo($orderId, $skuId);
			//创建完订单后 佣金已完成，更新用户余额
			if ($orderRes['status'] == 100 && $orderRes['order_detail']['order_info']['order_status'] == 100) {
				$res = OrderService::updateUserBalance($orderId);
				if (!$res) {
					Log::error('更新用户余额失败：' . $orderId);
					throw new Exception('更新用户余额失败：' . $orderId);
				}
			}

			$result = $this->createOrderSaveData($orderId, $skuId, $orderRes);

			if (strtotime($startTime) <= strtotime('2025-08-04 21:52:36')) {
				$result['save']['user_id'] = 0;
			}


			if (empty($result['save']) || empty($result['infoSave'])) {
				Log::error('创建订单失败：' . $orderId);
				throw new Exception('创建订单失败：' . $orderId);
			}

			//开启事物
			Db::transaction(function () use ($result, $orderRes) {
				// 创建订单记录
				$res     = Order::create($result['save']);
				$orderId = $res->id;

				// 创建订单详情
				$result['infoSave']['order_id'] = $orderId;
				OrderInfo::create($result['infoSave']);

				if ($result['save']['user_id'] != 0) {
					//把用户设置为老用户
					User::where('id', $result['save']['user_id'])->update([
						'is_new' => 0,
					]);

					// 如果状态为已取消，则不添加佣金记录
					$balanceLogData = [];
					if (!in_array($orderRes['status'], [200, 250])) {
						// 创建佣金记录
						if (!empty($result['commissionLog'])) {
							$userBalanceLogModel = new UserBalanceLog();
							$balanceLogData[]    = $userBalanceLogModel->create($result['commissionLog']);
						}
						// 创建邀请人佣金记录
						if (!empty($result['pUserCommissionLog'])) {
							$userBalanceLogModel = new UserBalanceLog();
							$balanceLogData[]    = $userBalanceLogModel->create($result['pUserCommissionLog']);
						}
					}

					//创建完订单后 佣金已完成，更新用户余额
					if ($orderRes['status'] == 100 && $orderRes['order_detail']['order_info']['order_status'] == 100) {
						$res = $this->updateUserBalance($res, $balanceLogData);
						if (!$res) {
							Log::error('更新用户余额失败：' . $orderId);
							throw new Exception('更新用户余额失败：' . $orderId);
						}
					}
				}
			});


			echo "当前nextKey: {$nextKey}\n";
			echo "订单ID:{$orderId}\n";
			echo "SKU_ID:{$skuId}\n";
			echo "已执行完成\n";
			return;
		} catch (Exception $e) {
			$log = [
				'msg'   => '获取订单详情失败',
				'error' => $e->getMessage(),
				'data'  => $item,
			];
			Log::error($log);
			return;
		}
	}

	/**
	 * @throws Exception
	 */
	private function updateOrderHandle($orderId, $skuId, $item, $nextKey, $startTime)
	{
		//@tips 回调脚本中有对应处理
	}

	/**
	 * @throws Exception
	 */
	private function createOrderSaveData(string $orderId, string $skuId, array $orderRes): array
	{
		$shopInfo       = $orderRes['order_detail']['shop_info'] ?? [];
		$productInfo    = $orderRes['order_detail']['product_info'] ?? [];
		$orderInfo      = $orderRes['order_detail']['order_info'] ?? [];
		$commissionInfo = $orderRes['order_detail']['commission_info'] ?? [];
		$buyerInfo      = $orderRes['order_detail']['buyer_info'] ?? [];

		Log::error('推客信息：' . json_encode($commissionInfo, JSON_UNESCAPED_UNICODE));
		Log::error('购买者信息：' . json_encode($buyerInfo, JSON_UNESCAPED_UNICODE));
		//获取推客ID
		$sharerAppid = $commissionInfo['sharer_info']['sharer_appid'] ?? '';
		if (empty($sharerAppid)) {
			Log::error('推客信息不存在：' . json_encode($commissionInfo, JSON_UNESCAPED_UNICODE));
		}

		$user = [];
		if ($sharerAppid) {
			$user = User::field('id, parent_user_id, level, agent_id')->where('status', User::STATUS_YES)->where('sharer_appid', $sharerAppid)->find();
			if (empty($user)) {
				Log::error('用户不存在：' . $sharerAppid);
			}
		}

		$userId  = $user['id'] ?? 0;
		$agentId = $user['agent_id'] ?? 0;

		//推客机构分佣信息
		$promoterAgencyInfo = $commissionInfo['promoter_agency_info'] ?? [];
		if (empty($promoterAgencyInfo)) {
			Log::error('推客机构分佣信息不存在：' . json_encode($commissionInfo, JSON_UNESCAPED_UNICODE));
		}

		//获取商品自增ID
		$productId = $productInfo['product_id'];
		$shopAppid = $shopInfo['appid'];
		$goodsInfo = Goods::field('id, commission, share_commission, subsidy_commission, partners_subsidy_push, partners_subsidy_shop')->where('product_id', $productId)->where('shop_appid', $shopAppid)->find();
		if (empty($goodsInfo)) {
			Log::error('商品不存在：' . json_encode($productInfo, JSON_UNESCAPED_UNICODE));
		}
		$goodsId = $goodsInfo['id'] ?? 0;
		//商品售价
		$salePrice = $productInfo['actual_payment'];
		//实际佣金（机构佣金）
		$actualCommission = $promoterAgencyInfo['amount'] ?? 0;

		$isFree = $commission = $shareCommission = $subsidyCommission = $oneCommission = $agentCommission = $agentPushCommission = $agentShopCommission = $agentShopAgent = 0;
		//推客分享赚佣金
		$setting = [];
		if ($user) {
			$setting = AgentDistribution::getLevelInfo($agentId, $user['level'], 1);
		}
		$agent_ratio     = $setting['agent_ratio'] ?? 0; //合作商佣金比例
		$ratio           = isset($setting['ratio']) ? $setting['ratio'] / 100 : 0; //推客分享赚佣金比例
		$type            = $setting['type'] ?? 0; //分销类型，0：关闭，1：一级
		$ratio_one       = isset($setting['ratio_one']) ? $setting['ratio_one'] / 100 : 0; //一级分销比例
		$shareCommission = round($actualCommission * $ratio);

		//判断商品是否0元购
		$free = GoodsFree::where('goods_id', $goodsId)->value('id');
		//如果商品是0元购，则补贴佣金 = 商品售价 - 实际佣金
		if ($free) {
			// TODO 零元购不分佣，那这里是不是有问题？？
			$isFree            = 1;
			$subsidyCommission = $salePrice - $actualCommission;
		} else {
			$subsidyCommission = $goodsInfo['subsidy_commission'] ?? 0;
			//如果开启分销，且用户有上级，则一级分销佣金 = 实际佣金 * 一级分销比例
			if ($type && $user && $user['parent_user_id'] > 0 && $ratio_one > 0) {
				$oneCommission = round($actualCommission * $ratio_one);
			}
		}
		//直推或自购佣金 = 分享赚佣金 + 补贴佣金
		$commission = $shareCommission + $subsidyCommission;
		if ($agentId && $goodsInfo && $goodsInfo['partners_subsidy_push'] > 0) {
			$agentPushCommission = $goodsInfo['partners_subsidy_push'];
		}
		//如果小店在合作商下且有小店补贴佣金，则添加小店补贴佣金
		if ($goodsInfo && $goodsInfo['partners_subsidy_shop'] > 0) {
			$agentShopAgent      = AgentShop::where('appid', $shopAppid)->value('agent_id');
			$agentShopCommission += $goodsInfo['partners_subsidy_shop'];
		}
		if ($user && $user['agent_id'] > 0) {
			//合作商佣金 = 实际佣金 * 合作商佣金比例 + 补贴推客佣金 + 补贴小店佣金
			$agentCommission = round($actualCommission * $agent_ratio + $agentPushCommission);
		}
		if ($agentShopAgent > 0 && $agentShopAgent == $agentId) {
			$agentCommission += $agentShopCommission;
		}
		//利润 = 实际佣金 - 推客佣金 - 合作商佣金
		$profit = $actualCommission - $agentCommission - $commission;

		$save     = [
			'user_id'                  => $userId,
			'agent_id'                 => $agentId,
			'goods_id'                 => $goodsId,
			'product_id'               => $productId,
			'shop_appid'               => $shopAppid,
			'order_id'                 => $orderId,
			'sku_id'                   => $skuId,
			'title'                    => $productInfo['title'],
			'image'                    => $productInfo['thumb_img'] ?? '',
			'total'                    => $salePrice,
			'actual_commission'        => $actualCommission,
			'commission'               => $commission,
			'share_commission'         => $shareCommission,
			'subsidy_commission'       => $subsidyCommission,
			'one_commission'           => $oneCommission,
			'agent_commission'         => $agentCommission,
			'agent_subsidy_commission' => $agentPushCommission,
			'agent_shop_commission'    => $agentShopCommission,
			'agent_shop_agent'         => $agentShopAgent,
			'profit'                   => $profit,
			'is_free'                  => $isFree,
			'status'                   => $orderInfo['order_status'],
			'commission_status'        => $orderRes['status'],
		];
		$infoSave = [
			'shop_info'       => json_encode($shopInfo, JSON_UNESCAPED_UNICODE),
			'product_info'    => json_encode($productInfo, JSON_UNESCAPED_UNICODE),
			'order_info'      => json_encode($orderId, JSON_UNESCAPED_UNICODE),
			'commission_info' => json_encode($commissionInfo, JSON_UNESCAPED_UNICODE),
			'buyer_info'      => json_encode($buyerInfo, JSON_UNESCAPED_UNICODE),
		];

		$commissionLog = [];
		if ($user) {
			$money = round($commission / 100, 2);
			if ($money > 0) {
				$commissionLog = [
					'user_id'      => $userId,
					'from_user_id' => $userId,
					'type'         => UserBalanceLog::TYPE_NEED_RECEIVE,
					'scene'        => UserBalanceLog::SCENE_SHARE_ORDER,
					'money'        => $money,
					'order_money'  => round($salePrice / 100, 2),
					'order_id'     => $orderId,
				];
			}
		}

		$pUserCommissionLog = [];
		if ($user && $user['parent_user_id'] > 0) {
			$pUser = User::field('id, parent_user_id, level, agent_id')->where('id', $user['parent_user_id'])->find();
			if (!empty($pUser) && $pUser['level'] >= 2) {
				$config             = Config::where('name', '=', 'real_name')->value('value');
				$pUserCommissionLog = [
					'user_id'      => $pUser['id'],
					'from_user_id' => $userId,
					'type'         => UserBalanceLog::TYPE_NEED_RECEIVE,
					'scene'        => UserBalanceLog::SCENE_CREATE_ORDER,
					'money'        => $config,
					'order_money'  => round($salePrice / 100, 2),
					'order_id'     => $orderId,
				];
			}
		}

		return [
			'save'               => $save,
			'infoSave'           => $infoSave,
			'commissionLog'      => $commissionLog,
			'pUserCommissionLog' => $pUserCommissionLog,
		];
	}


	/**
	 * 更新用户余额
	 *
	 * @param $order
	 * @param $balanceLogData
	 * @return bool
	 */
	public static function updateUserBalance($order, $balanceLogData)
	{
		$user = User::field('id, parent_user_id, total, money, agent_id, order_count, rank')
			->where('id', $order['user_id'])
			->where('status', User::STATUS_YES)
			->find();
		if (!$user) {
			Log::error('用户不存在：' . $order['user_id']);
			return true;
		}
		$user_res = User::where('id', $user['id'])->update([
			'order_count' => $user['order_count'] + 1,
		]);
//        $parent_user_res = true;
//        //给推客上级用户添加佣金
//        if ($user['parent_user_id'] > 0) {
//            $parent_user = User::field('id, total, money, agent_id')->where('id', $user['parent_user_id'])->find();
//            if ($parent_user) {
//                $parent_user_res = User::where('id', $parent_user['id'])->update([
//                    'total' => $parent_user['total'] + $order['one_commission'],
//                    'money' => $parent_user['money'] + $order['one_commission'],
//                ]);
//            }
//        }

		// 佣金奖励
		$userModel           = new User();
		$UserBalanceLogModel = new UserBalanceLog();

		$updateStatusLogIds = [];
		// 将分佣金额加到用户余额
		foreach ($balanceLogData as $value) {
			$updateStatusLogIds[] = $value['id']; // 提交事物之前，会将主键id放入 id 字段，无论主键id是否叫做id
			$userModel->setIncMoney($value['user_id'], $value['money'] * 100);
			$userModel->setIncTotal($value['user_id'], $value['money'] * 100);
		}

		// 给用户账户分佣后，将状态改为已结算
		$UserBalanceLogModel->whereIn('log_id', $updateStatusLogIds)->update([
			'status' => UserBalanceLog::STATUS_COMPLETED,
		]);

		// 团队奖励
		$team_ids      = explode('|', trim($user['rank'], '|'));
		$team_ids      = array_reverse(array_slice(array_reverse($team_ids), 0, 9));
		$team_user_ids = $userModel->where('id', 'in', $team_ids)->where('level', '=', 3)->column('id');

		// 获取当前分佣队列开头的数据
		$firstOrderTeamCommissionId = OrderTeamCommissionLogModel::where('user_id', $order['user_id'])
			->where('level', 1)
			->order('id', 'desc')
			->value('id');
		// 获取当前分佣队列数据
		$orderTeamCommissionLogCount = OrderTeamCommissionLogModel::where('user_id', $order['user_id'])
			->where('id', '>=', $firstOrderTeamCommissionId)
			->count();
		$orderTeamCommissionLogCount = intval($orderTeamCommissionLogCount);
		$nextUserId                  = $team_ids[0];
		$level                       = 1;

		if ($orderTeamCommissionLogCount < count($team_ids)) {
			$nextUserId = $team_ids[$orderTeamCommissionLogCount];
			$level      = $orderTeamCommissionLogCount + 1;
		}
		if ($orderTeamCommissionLogCount == count($team_ids)) {
			$nextUserId = 0;
			$level      = $orderTeamCommissionLogCount + 1;
		}

		if (in_array($nextUserId, $team_user_ids)) {
			$setting     = DistributionSetting::getLevelInfo(3, 1);
			$team_reward = round($setting['team_ratio'] * $order['actual_commission'] / 10000, 2);

			if ($team_reward > 0) {
				// 将金额发放到用户余额 && 累计总收益金额
				Log::error("将金额发放到用户余额 && 累计总收益金额");
				$userModel->setIncMoney($nextUserId, $team_reward * 100);
				$userModel->setIncTotal($nextUserId, $team_reward * 100);

				// 创建分佣记录信息
				UserBalanceLog::create([
					'user_id'      => $nextUserId,
					'from_user_id' => $user['id'],
					'type'         => UserBalanceLog::TYPE_NEED_RECEIVE,
					'scene'        => UserBalanceLog::SCENE_TEAM,
					'money'        => $team_reward,
					'order_money'  => round($order['total'] / 100, 2),
					'order_id'     => $order['order_id'],
					'status'       => UserBalanceLog::STATUS_COMPLETED,
				]);

				// 添加订单团队分佣记录表 给系统分佣的话，也需要记录
				OrderTeamCommissionLogModel::create([
					'level'                     => $level,
					'user_id'                   => $order['user_id'],
					'order_id'                  => $order['id'],
					'commission_user_id'        => $nextUserId,
					'actual_commission_user_id' => in_array($nextUserId, $team_user_ids) ? $nextUserId : 0,
					'created_at'                => date('Y-m-d H:i:s'),
					'updated_at'                => date('Y-m-d H:i:s'),
				]);
			}
		}

//        // 满足条件时升级v2
//        if ($user['level'] == 1) {
//            $setting     = DistributionSetting::getLevelInfo($user['level'], 1);
//            if ($user['order_count'] + 1 >= $setting['order_count']) {
//                User::where('id', $user['id'])->update(['level' => 2]);
//            }
//        }

		$agent_res = $shop_agent_res = true;
		if ($order['agent_id'] > 0) {
			$agent = AdminAgent::field('id, total_money, money')->where('id', $order['agent_id'])->find();
			//如果小店补贴佣金跟推客所属的合作商不一样，则代理商佣金需要减去小店补贴佣金
			$shop_agent = null;
			if ($order['agent_id'] != $order['agent_shop_agent']) {
				$agent_commission = $order['agent_commission'] - $order['agent_shop_commission'];
				$shop_agent       = AdminAgent::field('id, total_money, money')->where('id', $order['agent_shop_agent'])->find();
			} else {
				$agent_commission = $order['agent_commission'];
			}

			$agent_res = AdminAgent::where('id', $agent['id'])->update([
				'total_money' => $agent['total_money'] + $agent_commission,
				'money'       => $agent['money'] + $agent_commission,
			]);
			if ($shop_agent) {
				$shop_agent_res = AdminAgent::where('id', $order['agent_shop_agent'])->update([
					'total_money' => $shop_agent['total_money'] + $order['agent_shop_commission'],
					'money'       => $shop_agent['money'] + $order['agent_shop_commission'],
				]);
			}
		}
		if ($user_res /*&& $parent_user_res*/ && $agent_res && $shop_agent_res) {
			return true;
		}
		return false;
	}
}
